#include "thrdpool.hpp"
#include "loger.hpp"

sl::ThrdPool::ThrdPool()
{
    size_t thread_count = std::thread::hardware_concurrency();
    start_workers(thread_count);
}

sl::ThrdPool::ThrdPool(size_t thread_count)
{
    if(thread_count == 0) {
        thread_count = std::thread::hardware_concurrency();
    }
    start_workers(thread_count);
}

sl::ThrdPool::~ThrdPool()
{
    {
        std::unique_lock lock(mtx_);
        stopped_ = true;
    }
    cv_.notify_all();
}

void sl::ThrdPool::start_workers(size_t thread_count)
{
    workers_.reserve(thread_count);
    for(size_t i = 0; i < thread_count; ++i) {
        // 每个工作线程绑定 worker_loop 函数，接收 stop_token
        workers_.emplace_back(
            [this, thrd_index = i]() { worker_loop(thrd_index); });
    }
}

void sl::ThrdPool::worker_loop(size_t index)
{
    sl::loger::debug("thread {} start", index);
    while(true) {
        std::function<void()> task;
        {
            std::unique_lock lock(mtx_);
            cv_.wait(lock,
                [this]() { return (stopped_ == true) || !tasks_.empty(); });

            if(tasks_.empty()) {
                break;
            }

            task = std::move(tasks_.front());
            tasks_.pop();
        }

        try {
            task();
        } catch(const std::exception& e) {
            sl::loger::error("task run raise exception:{}", e.what());
        }
    }
    sl::loger::debug("thread {} stop", index);
}